<template>
  <div class="t-stepper-wrap" :class="'t-stepper-outer-name-' + step">
    <QStepper
      ref="refComponent"
      v-bind="{ ...attrs, ...{class: null, style: null, id: null}, ...mappingProps }"
      :modelValue="step"
      @update:modelValue="e => updateModelValue(e)"
      v-show="mappingProps.visible"
      class="t-stepper"
      :class="[isMobile ? 't-stepper-mobile' : 't-stepper-pc', staticItemsComputed.find(item => item.caption) ? 't-stepper-has-caption' : '', staticItemsComputed.find(item => item?.caption?.length > 10) ? 't-stepper-has-caption-and-long' : '']"
      :alternative-labels="alternativeLabelsComputed"
      :vertical="verticalComputed"
      :header-nav="inDesign ? true : mappingProps.headerNav"
      :keep-alive="true"
      @before-transition="beforeTransition"
      @transition="transition"
      :tabIndex="mappingProps.headerNav ? mappingProps.tabIndex : -1"
    >
      <!--
        1.组件中进行国际化配置 - 需要在 studio 中 点一下 ”静态数据源“配置弹窗 的确认按钮，才能触发生效；且自动翻译的词条有问题
        v-for="(item, index) of staticItemsComputed"

        2.常规方案，辰哥，春辉 在 studio 已经处理好了，只需要配置“静态数据源”的元数据即可
        v-for="(item, index) of mappingProps.staticItems"

        2024.07.15 还是需要自己写。。。所以改回 staticItemsComputed, 里面用到 接口返回的 国际化词条字段
      -->
      <QStep
        v-for="(item, index) of staticItemsComputed"
        :name="item.name"
        :prefix="!mappingProps.inactiveIcon ? item.name : ''"
        :title="item.title"
        :caption="isMobile ? '' : item.caption"
        class="outer outer1111111111111"
        :class="'outer-' + (index + 1)"
        :done="item.done"
        :error="item.error"
        :disable="item.disable"
      >
        <!-- 不使用 stepper 自带的 default 插槽了, 会导致多余渲染 =>  -->
        <!-- <slot defaultProps="defaultProps" :nameCurrent="item.name"> </slot> -->
        <!-- <slot></slot> -->
      </QStep>
      <!-- 同时也 不使用 stepper 自带的 navigation 插槽了 -->
    </QStepper>
    <div class="q-stepper__content-self">
      <slot></slot>
    </div>
    <div :class="verticalComputed ? 'q-stepper--vertical' : 'q-stepper--horizontal'">
      <div class="q-stepper__nav" v-if="mappingProps.isShowNav">
        <TBtn v-if="step > 1" @click="mappingProps.clickPrevious ? mappingProps.clickPrevious() : clickPreviousDefault()" :label="$q.lang.stepper?.previous || '上一步'" class="tr-button-primary button-next" :tabIndex="mappingProps.tabIndex"/>
        <TBtn @click="mappingProps.clickNext ? mappingProps.clickNext() : clickNextDefault()" :label="step >= staticItemsComputed[staticItemsComputed.length - 1]?.name ? ($q.lang.stepper?.done || '完成') : ($q.lang.stepper?.next || '下一步')" class="tr-button-primary" :tabIndex="mappingProps.tabIndex"/>
      </div>
    </div>
  </div>
</template>
<script setup>
import QStep, { QStepper, QStepperNavigation } from '@teld/q-components/Stepper';
import TBtn from '../button';
import useMappingProps from 't/common/hooks/useMappingProps';
import { commonProps } from 't/common/utils';
import { onMounted, ref, useAttrs, watch, computed } from 'vue';
import { useQuasar } from '@teld/q-components';

const Funcs = window.Funcs || {
  GetTerms: (c, n) => n,
};
const refComponent = ref();
const attrs = useAttrs();
const props = defineProps({
  ...commonProps,
  ...QStepper.props,

  // 静态数据源 - 每一个 item 是子组件(step) 的属性
  staticItems: {
    type: Array,
    default() {
      return [];
    },
  },
  isShowNav: {
    type: Boolean,
    default() {
      return true
    }
  },
  // modelValue

  modelValue: {
    type: [Number, String],
    default() {
      return null
    }
  },
  // 本来就有 (√ - 暴露, × - 不暴露)
  // infinite: Boolean, // ×
  // swipeable: Boolean, // ×
  // contracted: Boolean // ×
  // animated: Boolean // × - 默认值改为 true
  animated: {
    type: Boolean,
    default() {
      return true
    }
  },
  // vertical: Boolean, // √
  // headerNav: Boolean, // √
  headerNav: {
    type: Boolean,
    default() {
      return false;
    },
  },
  // alternativeLabels: Boolean, // √
  alternativeLabels: {
    type: [Boolean, String],
    default() {
      return false
    }
  },

  // inactiveColor: String, // √
  inactiveColor: {
    type: String,
    default() {
      return 'rgba(0, 0, 0, 0.56)'
    }
  },
  // doneColor: String, // √
  doneColor: {
    type: String,
    default() {
      return 'var(--t-color)' // pc端设计图，原来是这个，rgb(35, 148, 255) -- 元数据默认保持这个，这里换乘主色变量因为移动端 复杂组件引用我们stepper 默认不传参数，做到最简改动
    }
  },
  // activeColor: String, // √
  activeColor: {
    type: String,
    default() {
      return 'var(--t-color)' // pc端设计图，原来是这个，rgb(0, 157, 255) -- 元数据默认保持这个
    }
  },
  // errorColor: String, // √
  errorColor: {
    type: String,
    default() {
      return 'rgb(255,90,102)' // #FF5A66
    }
  },

  // inactiveIcon: String, // √
  // doneIcon: String, // √
  // activeIcon: String, // √
  // errorIcon: String, // √

  clickNext: {
    type: [Function, null], // 增加 null
    default() {
      return null
    }
  },
  clickPrevious: {
    type: [Function, null], // 增加 null
    default() {
      return null
    }
  },
  headerWidth: {
    type: String,
    default() {
      return ''
    }
  },
  // 低代码传入的是 tabIndex，而非 tabindex, 就是为了覆盖前者
  tabIndex: {
    type: [String, Number],
    default() {
      return 0;
    },
  },
});
const [mappingProps, mappingExpose] = useMappingProps(props);
const emit = defineEmits(['click', 'update:modelValue', 'before-transition', 'transition']);
const beforeTransition = (params) => {
  emit('before-transition', params)
}
const transition = (params) => {
  emit('transition', params)
}
// 设备是否是移动设备 isMobile => xs (此处使用xs)
// {
//   platform: {
//     is: { mobile: isMobile },
//   },
//   screen: { xs },
// }
const $q = useQuasar();
const stepDefault = ref(1)
const step = ref(stepDefault.value);
defineExpose({ ...mappingExpose, step });
onMounted(() => {
  refComponent.value.$el.querySelectorAll('.q-stepper__caption').forEach(item => item.title = item.innerText)
})
const isMobile = computed(() => $q.screen.xs || $q.platform.is.mobile)
// mobile 端 只能为 false -- 非竖版(横版)
const verticalComputed = computed(() => !isMobile.value ? mappingProps.vertical : false)
// mobile 端 只能为 true -- 标题在下
const alternativeLabelsComputed = computed(() => !isMobile.value ? mappingProps.alternativeLabels === true || mappingProps.alternativeLabels === '1' : true)

watch(
  () => mappingProps.modelValue,
  (newVal, oldVal) => {
    if (typeof newVal === 'number') step.value = newVal
  },
  { immediate: true}
)
watch(
  () => mappingExpose.staticItems,
  (newVal, oldVal) => {
    if(JSON.stringify(mappingProps.staticItems) === JSON.stringify(mappingExpose.staticItems.value)) return
    mappingProps.staticItems = mappingExpose.staticItems.value
  },
  {
    deep: true
  }
)

const staticItemsComputed = computed(() => {
  return (mappingProps?.staticItems || []).map(v => ({
    ...v,
    title: Funcs.GetTerms(v.title == '步骤1' ? ('Schema.Controls.fasr_stepper.step' + '1') : v.title == '步骤2' ? ('Schema.Controls.fasr_stepper.step' + '2') : v.title == '步骤3' ? ('Schema.Controls.fasr_stepper.step' + '3') : v.ValueInfo_title?.ReferenceExpr, v.title) || v.title,
    caption: Funcs.GetTerms(v.ValueInfo_caption?.ReferenceExpr, v.caption) || v.caption
  }))
})
const clickNextDefault = () => {
  refComponent.value.next()
}
const clickPreviousDefault = () => {
  refComponent.value.previous()
}
const updateModelValue = e => {
  emit('update:modelValue', e);
  if ((typeof mappingProps.modelValue) === 'number') return
  step.value = e;
}

const inDesign = ref(!!window['fas']?.inDesign);
function onClickHandler(params) {
  emit('click', params);
}
</script>

<style lang="scss">
.t-stepper-wrap {
  background: #fff;
  .show {
    height: auto;
  }
  .hide {
    height: 0;
    overflow: hidden;
  }
  .q-stepper {
    box-shadow: none;
    // 去除quasar样式 - 外框和内部标题的下分割线
    .q-stepper__header--border{
      width: v-bind(headerWidth);
      border-bottom: 0px;
    }
    .q-stepper__tab {
      // padding-left: 0; // 原为 24px;
      // padding-bottom: 0; // 原为 8px;
      flex: 1 1 0; // 保证每一步等宽 -- 目的是为了让线条等宽
    }
  }
  .q-stepper.q-stepper--horizontal {
    .q-stepper__tab {
      padding: 0;
      min-height: 0;
    }
    &.t-stepper-pc {
      .q-stepper__tab {
        margin-bottom: 25px;
        min-width: 175px; // 保持美观
      }
    }
  }
  // 去除完成
  .q-stepper__dot {
    min-width: 18px;
    width: 18px;
    height: 18px;
    line-height: 18px;
  }
  .q-stepper__title {
    line-height: 14px; // 方便计算 原来是 16px
    // font-size: 14px; // 默认已是这样
    color: rgba(0, 0, 0, 0.56);
  }
  .q-stepper__tab--active .q-stepper__title {
    color: v-bind(activeColor);
    font-weight: bold;
  }
  .q-stepper__caption {
    margin-top: 12px;
  }
  .t-stepper-has-caption .q-stepper__header--standard-labels .q-stepper__tab {
    padding-bottom: 23px; // 为了副标题留的 18px (行高18px * 1行) // quasar 原为 8px;
  }
  .t-stepper-has-caption.t-stepper-has-caption-and-long .q-stepper__header--standard-labels .q-stepper__tab {
    padding-bottom: 41px; // 为了副标题留的 36px (行高18px * 2行) // quasar 原为 8px;
  }
  .q-stepper__header--standard-labels, .q-stepper__header--alternative-labels {
    .q-stepper__caption {
      width: 10em;
      line-height: 18px; // 12 -> 18px
      font-size: 12px;
      color: rgba(0, 0, 0, 0.36);

      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
    }
  }
  .q-stepper__header--standard-labels {
    .q-stepper__caption {
      position: absolute;
      top: 9px;// 期待 12px - 去除行高18px 造成的 3px -> 9px;
      left: 0;
    }
    .q-stepper__tab {
      position: relative;
      min-width: 175px; // 保证副标题能展示完整 10字/行 * 2行
    }
    .q-stepper__label.relative-position {
      position: static;
    }
  }
  .q-stepper__header--alternative-labels {
    .q-stepper__label {
      margin-top: 12px;
    }
  }
  .q-stepper--horizontal .q-stepper__step-inner,
  .q-stepper--vertical .q-stepper__step-inner {
    padding: 0;
    // padding: 32px 24px 16px; 标准是这样的
  }
  .q-stepper__nav {
    display: flex;
    justify-content: flex-end;
  }
  .button-next {
    margin-left: 8px;
    margin-right: 8px;
  }
}
.t-stepper-next-button-wrap {
  display: flex;
  margin-top: 12px;
  justify-content: flex-end;
  .t-stepper-next-button, .t-stepper-prev-button {
    margin-left: 8px;
  }
}
// 自定义 容器
.t-stepper-wrap {
  .q-stepper__content-self > div {
    display: none;
  }
}
// 有 css 借助变量的写法吗？
.t-stepper-outer-name-1 .q-stepper__content-self {
  .inner_1 {
    display: block;
  }
}
.t-stepper-outer-name-2 .q-stepper__content-self {
  .inner_2 {
    display: block;
  }
}
.t-stepper-outer-name-3 .q-stepper__content-self {
  .inner_3 {
    display: block;
  }
}
.t-stepper-outer-name-4 .q-stepper__content-self {
  .inner_4 {
    display: block;
  }
}
.t-stepper-outer-name-5 .q-stepper__content-self {
  .inner_5 {
    display: block;
  }
}
.t-stepper-outer-name-6 .q-stepper__content-self {
  .inner_6 {
    display: block;
  }
}
.t-stepper-outer-name-7 .q-stepper__content-self {
  .inner_7 {
    display: block;
  }
}
.t-stepper-outer-name-8 .q-stepper__content-self {
  .inner_8 {
    display: block;
  }
}
.t-stepper-outer-name-9 .q-stepper__content-self {
  .inner_9 {
    display: block;
  }
}
.t-stepper-outer-name-10 .q-stepper__content-self {
  .inner_10 {
    display: block;
  }
}
.t-stepper-outer-name-11 .q-stepper__content-self {
  .inner_11 {
    display: block;
  }
}
.t-stepper-outer-name-12 .q-stepper__content-self {
  .inner_12 {
    display: block;
  }
}
.t-stepper-outer-name-13 .q-stepper__content-self {
  .inner_13 {
    display: block;
  }
}
.t-stepper-outer-name-14 .q-stepper__content-self {
  .inner_14 {
    display: block;
  }
}
.t-stepper-outer-name-15 .q-stepper__content-self {
  .inner_15 {
    display: block;
  }
}
.t-stepper-outer-name-16 .q-stepper__content-self {
  .inner_16 {
    display: block;
  }
}
.t-stepper-outer-name-17 .q-stepper__content-self {
  .inner_17 {
    display: block;
  }
}
.t-stepper-outer-name-18 .q-stepper__content-self {
  .inner_18 {
    display: block;
  }
}
.t-stepper-outer-name-19 .q-stepper__content-self {
  .inner_19 {
    display: block;
  }
}
.t-stepper-outer-name-19 .q-stepper__content-self {
  .inner_19 {
    display: block;
  }
}
.t-stepper-outer-name-20 .q-stepper__content-self {
  .inner_20 {
    display: block;
  }
}
// 自定义 容器
.outer {
  // .q-stepper__step-inner > div 运行时依靠这个生效
  .inner, div[class0="inner"], .q-stepper__step-inner > div {
    display: none;
  }
}

.outer.outer-1 {
  /* .q-stepper__step:nth-child(1) {
    display: block;
  } */
  .inner_1, div[instancecode="inner_1"], div[class2="inner_1"] {
    display: block;
  }
  /* div[instancecode="inner_1"] {
    display: block;
  }
  div[class2="inner_1"] {
    display: block;
  } */
}
.outer.outer-2 {
  .inner_2, div[instancecode='inner_2'] {
    display: block;
  }
}
.outer.outer-3 {
  .inner_3, div[instancecode='inner_3'] {
    display: block;
  }
}
.outer.outer-4 {
  .inner_4, div[instancecode='inner_4'] {
    display: block;
  }
}
.outer.outer-5 {
  .inner_5, div[instancecode='inner_5'] {
    display: block;
  }
}
.outer.outer-6 {
  .inner_6 {
    display: block;
  }
}
.outer.outer-7 {
  .inner_7 {
    display: block;
  }
}
.outer.outer-8 {
  .inner_8 {
    display: block;
  }
}
.outer.outer-9 {
  .inner_9 {
    display: block;
  }
}
.outer.outer-10 {
  .inner_10 {
    display: block;
  }
}
.outer.outer-11 {
  .inner_11 {
    display: block;
  }
}
.outer.outer-12 {
  .inner_12 {
    display: block;
  }
}
.outer.outer-13 {
  .inner_13 {
    display: block;
  }
}
.outer.outer-14 {
  .inner_14 {
    display: block;
  }
}
.outer.outer-15 {
  .inner_15 {
    display: block;
  }
}
.outer.outer-16 {
  .inner_16 {
    display: block;
  }
}
.outer.outer-17 {
  .inner_17 {
    display: block;
  }
}
.outer.outer-18 {
  .inner_18 {
    display: block;
  }
}
.outer.outer-19 {
  .inner_19 {
    display: block;
  }
}
.outer.outer-20 {
  .inner_20 {
    display: block;
  }
}
</style>

<style lang="scss">
.t-stepper-mobile {
  /* 横版 + 竖版 */
  &.q-stepper--vertical, &.q-stepper--horizontal {
    .q-stepper__header {
      .q-stepper__dot {
        width: 24px;
        height: 24px;
        font-size: 14px;
      }
      .q-stepper__title {
        line-height: 1.5; /* flag 影响到 3.5px 的 padding 可能需要调整, 先看一下评审效果吧 */
        max-width: 6.1em; /* 保持6个字，6.1em 是为了修正偏差 */
      }
      /* xs 没有 caption 所以 css 样式也 归零 */
      .q-stepper__caption {
        margin-top: 0;
      }
    }
  }
  /* 横版 */
  &.q-stepper--horizontal {
    .q-stepper__header--alternative-labels, .q-stepper__header--standard-labels {
      &.q-stepper__header {
        border-bottom: 10px solid var(--t-color-bg-gray);
        .q-stepper__tab {
          flex: 1 1 25%;
          min-height: unset;
          padding: 16px 0;
        }
      }
      .q-stepper__caption {
        width: 0; // 移动端不显示副标题 - 宽度也置零
      }
      /* 控制 间隔线 到 dot 的间距 */
      .q-stepper__label:after, .q-stepper__dot:after,
      .q-stepper__dot:before {
        background: var(--t-color-bg-gray);
        margin-left: 16px;
      }
      /* 控制 间隔线 到 dot 的间距 end */
    }
  }
}
</style>
